﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.ETL
{
    /// <summary>
    /// 
    /// </summary>
    public partial class HttpDownloadEditor : Form, IComponentEditor
    {
        private object _ActivityNode;
        private HttpDownloadComponent _HttpDownloader;

        /// <summary>
        /// 
        /// </summary>
        public HttpDownloadEditor()
        {
            InitializeComponent();
        }

        private void btn_Go_Click(object sender, EventArgs e)
        {
            this.RefreshWebPageAndLinks();
        }

        private void RefreshWebPageAndLinks()
        {
            if (string.IsNullOrEmpty(this.txt_RootUrl.Text))
                return;
            string url = this.txt_RootUrl.Text;
            if (!url.ToLower().StartsWith("http://"))
                url = "http://" + url;
            WebClient webClient = new WebClient();
            string tmpFile = Path.GetTempFileName(); 
            webClient.DownloadFile(url, tmpFile);
            this.webBrowser1.Navigate(tmpFile);
            StreamReader reader = new StreamReader(tmpFile);
            string content = reader.ReadToEnd();
            string linkPattern = this.txt_Pattern.Text;
            DataTable dt = this.ParseLinks(content, linkPattern);
            this.DisplayLinks(dt);
            this.webBrowser1.Navigate(url);
        }

        private void DisplayLinks(DataTable dt)
        {
            this.lv_Links.Items.Clear();
            this.lv_Links.Columns.Clear();
            if(dt.Columns !=null && dt.Columns.Count>0)
            {
                foreach(DataColumn col in dt.Columns)
                {
                    this.lv_Links.Columns.Add(col.ColumnName,100);
                }
            }
            if(dt.Rows!=null && dt.Rows.Count>0)
            {
                foreach(DataRow dr in dt.Rows)
                {
                    if(dr[0]==null || dr[0]==DBNull.Value)
                        continue;
                    ListViewItem lvItem=new ListViewItem(dr[0].ToString());
                    if(dt.Columns.Count>1)
                    {
                        for(int i=1;i<dt.Columns.Count;i++)
                        {
                            if (dr[i] == null || dr[i] == DBNull.Value)
                                lvItem.SubItems.Add("");
                            else
                                lvItem.SubItems.Add(dr[i].ToString());
                        }
                    }
                    this.lv_Links.Items.Add(lvItem);
                }
            }
            this.lv_Links.Refresh();
        }

        private DataTable ParseLinks(string htmlContent, string linkPattern)
        {
            DataTable dt=new DataTable();
            dt.Columns.Add("Name", typeof (string));
            dt.Columns.Add("Link", typeof(string));
            Regex linkHeaderRegex = new Regex(@"<a\s+([^>]+)>", RegexOptions.IgnoreCase);
            Regex nameValRegex=new Regex("href\\s*=\\s*'?\"?([^>'\"]+)'?\"?",RegexOptions.IgnoreCase);
            Regex linkTailRegex =new Regex("</a>", RegexOptions.IgnoreCase);
            Match headerMatch = linkHeaderRegex.Match(htmlContent);
            while(headerMatch.Success)
            {
                string aTag = headerMatch.Groups[1].Value;
                Match hrefMatch = nameValRegex.Match(aTag);
                string linkUrl = string.Empty;
                if(hrefMatch.Success)
                {
                    linkUrl = hrefMatch.Groups[1].Value;
                }
                Match tailMatch = linkTailRegex.Match(htmlContent, headerMatch.Index + headerMatch.Value.Length);
                if(!tailMatch.Success)
                    break;
                string header = htmlContent.Substring(headerMatch.Index + headerMatch.Value.Length,
                                                      tailMatch.Index - headerMatch.Index - headerMatch.Value.Length);
                bool addLink = true;
                if(!string.IsNullOrEmpty(linkPattern))
                {
                    if (!Regex.IsMatch(linkUrl, linkPattern, RegexOptions.IgnoreCase))
                        addLink = false;
                }
                if(addLink)
                {
                    DataRow dr = dt.NewRow();
                    dr["Name"] = header;
                    dr["Link"] = linkUrl;
                    dt.Rows.Add(dr);
                }

                headerMatch = linkHeaderRegex.Match(htmlContent, tailMatch.Index + tailMatch.Value.Length);
            }
            return dt;
        }

        #region Implementation of IComponentEditor

        public event UpdateComponentSettings UpdateComponentSettingEvent;

        /// <summary></summary>
        public object OwnerActivityNode
        {
            get { return _ActivityNode; }
            set { _ActivityNode = value; }
        }

        /// <summary></summary>
        public Type WorkflowComponentType
        {
            get { return typeof (HttpDownloadComponent); }
        }

        /// <summary></summary>
        public void LoadSettings(GlobalVariable[] globalVars, WorkflowComponentBase[] fromComponents, object activityNode, WorkflowComponentBase wfComponent)
        {
            this._ActivityNode = activityNode;
            this._HttpDownloader = (HttpDownloadComponent) wfComponent;
            HttpDownloadInstruction instruction = (HttpDownloadInstruction) this._HttpDownloader.Instruction;
            this.txt_RootUrl.Text = instruction.RootUrl;
            this.txt_Pattern.Text = instruction.DownloadLinkPattern;
            this.txt_Folder.Text = instruction.DownloadToFolder;
        }

        /// <summary></summary>
        public void SaveSettings()
        {
            HttpDownloadInstruction instruction = (HttpDownloadInstruction) this._HttpDownloader.Instruction;
            instruction.RootUrl = this.txt_RootUrl.Text;
            instruction.DownloadToFolder = this.txt_Folder.Text;
            instruction.DownloadLinkPattern = this.txt_Pattern.Text;
            this._HttpDownloader.Instruction = instruction;
        }

        /// <summary></summary>
        public TestResult Test()
        {
            throw new System.NotImplementedException();
        }

        #endregion

        private void btn_Parse_Click(object sender, EventArgs e)
        {
            this.RefreshWebPageAndLinks();
        }

        private void btn_OK_Click(object sender, EventArgs e)
        {
            this.SaveSettings();
            if (this.UpdateComponentSettingEvent != null)
                this.UpdateComponentSettingEvent(this._ActivityNode, this._HttpDownloader);
            this.Close();
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_Browse_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog dlg=new FolderBrowserDialog();
            if(dlg.ShowDialog()==DialogResult.OK)
                this.txt_Folder.Text = dlg.SelectedPath;
        }
    }
}
